package org.example.encrypt.typeHandler;

import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.example.encrypt.utils.NumberCryptUtil;

import java.math.BigDecimal;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * 数值类型参数加解密
 *
 * @Author WeiBing
 * @Create 2024/8/16 16:20
 */
@Slf4j
@MappedTypes({BigDecimal.class, Integer.class, Double.class})
@MappedJdbcTypes({JdbcType.DECIMAL, JdbcType.DOUBLE, JdbcType.INTEGER, JdbcType.BIGINT, JdbcType.DOUBLE})
public class NumberTypeHandler extends BaseTypeHandler<Number> {
    @Override
    public void setNonNullParameter(PreparedStatement ps, int index, Number param, JdbcType jdbcType) throws SQLException {
        if (null != param) {
            // 分别处理不同类型
            if (param instanceof BigDecimal) {
                BigDecimal numberParam = (BigDecimal) param;
                ps.setBigDecimal(index, NumberCryptUtil.encrypt(numberParam));
            } else if (param instanceof Integer) {
                Integer numberParam = (Integer) param;
                ps.setInt(index, NumberCryptUtil.encrypt(BigDecimal.valueOf(numberParam)).intValue());
            } else if (param instanceof Double) {
                Double numberParam = (Double) param;
                ps.setDouble(index, NumberCryptUtil.encrypt(BigDecimal.valueOf(numberParam)).doubleValue());
            } else {
                log.info("不支持的加密数值类型参数");
            }
        }
    }

    @Override
    public Number getNullableResult(ResultSet rs, String columnName) throws SQLException {
        Object object = rs.getObject(columnName);
        if (object instanceof BigDecimal) {
            BigDecimal numberValue = (BigDecimal) object;
            return NumberCryptUtil.decrypt(numberValue);
        } else if (object instanceof Integer) {
            Integer numberValue = (Integer) object;
            return NumberCryptUtil.decrypt(BigDecimal.valueOf(numberValue));
        } else if (object instanceof Double) {
            Double numberValue = (Double) object;
            return NumberCryptUtil.decrypt(BigDecimal.valueOf(numberValue));
        } else {
            log.info("不支持的解密数值类型");
        }
        return null;
    }

    @Override
    public Number getNullableResult(ResultSet rs, int index) throws SQLException {
        Object object = rs.getObject(index);
        if (object instanceof BigDecimal) {
            BigDecimal numberValue = (BigDecimal) object;
            return NumberCryptUtil.decrypt(numberValue);
        } else if (object instanceof Integer) {
            Integer numberValue = (Integer) object;
            return NumberCryptUtil.decrypt(BigDecimal.valueOf(numberValue));
        } else if (object instanceof Double) {
            Double numberValue = (Double) object;
            return NumberCryptUtil.decrypt(BigDecimal.valueOf(numberValue));
        } else {
            log.info("不支持的解密数值类型");
        }
        return null;
    }

    @Override
    public Number getNullableResult(CallableStatement cs, int index) throws SQLException {
        Object object = cs.getObject(index);
        if (object instanceof BigDecimal) {
            BigDecimal numberValue = (BigDecimal) object;
            return NumberCryptUtil.decrypt(numberValue);
        } else if (object instanceof Integer) {
            Integer numberValue = (Integer) object;
            return NumberCryptUtil.decrypt(BigDecimal.valueOf(numberValue));
        } else if (object instanceof Double) {
            Double numberValue = (Double) object;
            return NumberCryptUtil.decrypt(BigDecimal.valueOf(numberValue));
        } else {
            log.info("不支持的解密数值类型");
        }
        return null;
    }
}
